Skip to content

test: sell_confirm + sell_payment_info cubits (+15 tests)#341

Merged
TaprootFreak merged 2 commits into
developfrom
test/sell-confirm-cubit
May 15, 2026
Merged

test: sell_confirm + sell_payment_info cubits (+15 tests)#341
TaprootFreak merged 2 commits into
developfrom
test/sell-confirm-cubit

Conversation

@TaprootFreak
Copy link
Copy Markdown
Contributor

@TaprootFreak TaprootFreak commented May 15, 2026

Summary

Two sell-side cubits whose source files are NOT in PR #321's diff (only the underlying services are).

Cubit Test file Cases
`sell/cubits/sell_confirm/sell_confirm_cubit.dart` `test/screens/sell/cubits/sell_confirm_cubit_test.dart` 3
`sell/cubits/sell_payment_info/sell_payment_info_cubit.dart` `test/screens/sell/cubits/sell_payment_info_cubit_test.dart` 12

What each covers

  • sell_confirm_cubit: initial `SellConfirmInitial`; happy path passes through Loading and ends in Success (service mock suspends 10ms so the broadcast-stream listener can observe Loading); service throw → Failure carrying the error string.
  • sell_payment_info_cubit:
    • `getPaymentInfo` happy path emits Success with `isBitbox=false` for a `SoftwareWallet`; `isBitbox=true` for a `BitboxWallet` stub.
    • Exception mapping: `KycLevelRequiredException` → `Failure(kycRequired, requiredLevel)`; `RegistrationRequiredException` → `Failure(registrationRequired)`; generic → `Failure(unknown, message)`.
    • `validateMinAmount` (the parallel to buy_payment_info_cubit's min check, but here it's a CHF-10 floor): below floor emits `MinAmountNotMet`; above leaves the state untouched; EUR scaled by `getChfToEurRate` (ceil); a prior `MinAmountNotMet` is cleared back to `Initial` when the amount rises; comma decimal normalised to dot; empty string treated as 0.

Notes

  • Both cubits use `SellPaymentInfo` which has 13 required fields. Tests construct one real instance with stub addresses + a no-op Eip7702Data so the value can be passed around without mocktail fallback registration.
  • For the BitBox-wallet test, a tiny `_BitboxStubWallet extends AWallet` is used (only `walletType` is read; `primaryAccount` / `currentAccount` throw to make the intent explicit).

Test plan

  • `flutter analyze` on both new files — clean
  • `flutter test` — 15 / 15 passing locally
  • CI green

Stage 17 of the coverage push.

- sell_confirm_cubit (3): initial SellConfirmInitial; happy path
  passes through Loading and ends in Success (mock service suspends
  10ms so the broadcast stream listener can observe Loading);
  service throw → Failure carrying the error message
Adds full coverage for the sell-side payment-info cubit (no PR conflict
with #321 — the cubit source file is not in its diff, only the
underlying service is).

- initial state
- getPaymentInfo (5): happy with isBitbox=false for SoftwareWallet,
  isBitbox=true for BitboxWallet, KycLevelRequiredException,
  RegistrationRequiredException, generic exception
- validateMinAmount (6): CHF below 10 emits MinAmountNotMet; above
  leaves Initial; EUR scaled by getChfToEurRate (ceil); prior
  MinAmountNotMet is cleared back to Initial when amount rises;
  comma decimal normalised to dot; empty string treated as 0
@TaprootFreak TaprootFreak changed the title test: sell_confirm_cubit (+3 tests) test: sell_confirm + sell_payment_info cubits (+15 tests) May 15, 2026
@TaprootFreak TaprootFreak marked this pull request as ready for review May 15, 2026 11:47
@TaprootFreak TaprootFreak merged commit a6b8e72 into develop May 15, 2026
1 check passed
@TaprootFreak TaprootFreak deleted the test/sell-confirm-cubit branch May 15, 2026 11:48
TaprootFreak added a commit that referenced this pull request May 23, 2026
Tier-1 integration tests stitching SellBitboxCubit → FakeBitboxCredentials
boundary → real RealUnitSellPaymentInfoService → MockClient. The cubit and
the service are both real production code; only the BitBox transport and
the HTTP wire are stubbed. This pins:

* happy path — full swap+deposit ceremony emits two BitBox signs and the
  correct broadcast order/wire-shape (unsignedTx + r/s/v padding). Regression
  class: silently double-signing on the device or swapping leg order.

* cancel mid-swap — FakeBitboxBehavior.cancel propagates as
  SigningCancelledException all the way to SellBitboxError instead of
  being silently accepted as a successful sign (PR #322 bug class).

* disconnect — BitboxNotConnectedException is caught EXPLICITLY by the
  cubit's typed catch and emits SellBitboxBitboxRequired, not a generic
  Error state. Regression class: re-pair screen replaced by raw error
  string (PR #341).

* malformed signature — FormatException from a frame-desync hits the
  generic catch and surfaces as SellBitboxError, NOT mis-classified as a
  BitBox disconnect (would mask sig bugs as UX disconnect prompts).

* deposit-retry — transient 5xx on the deposit broadcast lands the cubit
  in SellBitboxDepositRetry with both signed envelopes preserved; the
  user does not have to re-sign on the device. Regression class:
  funds-at-risk loss of the already-signed swap (PR #338).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant